import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

public class OptimalVisualizer extends JFrame {
    private final Optimal optimal = new Optimal();
    private final JLabel[] memoryLabels = new JLabel[Optimal.N];
    private final JButton nextButton = new JButton("Next Step");
    private final JLabel statusLabel = new JLabel("Press 'Next Step' to start", SwingConstants.CENTER);
    private int currentStep = 0;
    private Integer[] pageSequence;

    public OptimalVisualizer() {
        setTitle("Optimal Page Replacement Visualization");
        setSize(600, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));
        getContentPane().setBackground(new Color(240, 240, 240));

        // 用户输入页面序列
        pageSequence = getPageSequenceFromUser();

        JPanel memoryPanel = new JPanel(new GridLayout(1, Optimal.N, 5, 5));
        memoryPanel.setBorder(BorderFactory.createTitledBorder("Memory Frames"));
        memoryPanel.setBackground(new Color(255, 255, 255));
        for (int i = 0; i < Optimal.N; i++) {
            memoryLabels[i] = new JLabel("Empty", SwingConstants.CENTER);
            memoryLabels[i].setOpaque(true);
            memoryLabels[i].setBackground(new Color(220, 220, 220));
            memoryLabels[i].setFont(new Font("Arial", Font.PLAIN, 16));
            memoryLabels[i].setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
            memoryPanel.add(memoryLabels[i]);
        }
        add(memoryPanel, BorderLayout.CENTER);

        JPanel bottomPanel = new JPanel(new BorderLayout(5, 5));
        statusLabel.setFont(new Font("Arial", Font.ITALIC, 14));
        statusLabel.setForeground(new Color(100, 100, 100));
        bottomPanel.add(statusLabel, BorderLayout.NORTH);

        nextButton.setFont(new Font("Arial", Font.BOLD, 14));
        nextButton.setBackground(new Color(70, 130, 180));
        nextButton.setForeground(Color.WHITE);
        nextButton.setFocusPainted(false);
        bottomPanel.add(nextButton, BorderLayout.CENTER);

        bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        add(bottomPanel, BorderLayout.SOUTH);

        nextButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (currentStep < pageSequence.length) {
                    Object replaced = optimal.push(pageSequence, currentStep);
                    updateMemoryDisplay(replaced);
                    statusLabel.setText("Current step: " + (currentStep + 1) + ", Accessed page: " + pageSequence[currentStep]);
                    currentStep++;
                } else {
                    nextButton.setEnabled(false);
                    statusLabel.setText("All steps completed!");
                    JOptionPane.showMessageDialog(OptimalVisualizer.this, "Simulation finished!", "Info",
                            JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
    }

    private void updateMemoryDisplay(Object replaced) {
        for (int i = 0; i < Optimal.N; i++) {
            Object value = optimal.getArray()[i];
            memoryLabels[i].setText(value == null ? "Empty" : value.toString());
            memoryLabels[i].setBackground(value == null ? new Color(220, 220, 220) : new Color(173, 216, 230));
        }
        if (replaced != null) {
            int replacedIndex = Arrays.asList(optimal.getArray()).indexOf(replaced);
            if (replacedIndex != -1) {
                memoryLabels[replacedIndex].setBackground(new Color(255, 182, 193)); // Highlight replaced frame
            }
        }
    }


private Integer[] getPageSequenceFromUser() {
    while (true) {
        try {
            String input = JOptionPane.showInputDialog(this, "Enter page sequence (space-separated):",
                    "Input Page Sequence", JOptionPane.QUESTION_MESSAGE);
            if (input == null) { // 用户取消输入
                JOptionPane.showMessageDialog(this, "No input provided. Exiting.", "Error",
                        JOptionPane.ERROR_MESSAGE);
                System.exit(0);
            }
            // 使用空格作为分隔符
            String[] parts = input.trim().split("\\s+");
            Integer[] sequence = new Integer[parts.length];
            for (int i = 0; i < parts.length; i++) {
                sequence[i] = Integer.parseInt(parts[i]);
            }
            return sequence;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Invalid input. Please enter space-separated integers.", "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
    }
}


    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            OptimalVisualizer frame = new OptimalVisualizer();
            frame.setVisible(true);
        });
    }
}
